Skip to content

Conversation

@johnstcn
Copy link
Member

  • Renames screentracker.Conversation -> screentracker.PTYConversation
  • Extracts Conversation interface (some methods renamed for brevity)
  • Renames FindLastMessage to screenDiff, moved to diff(_test).go along with relevant tests.

@johnstcn johnstcn self-assigned this Jan 22, 2026
@github-actions
Copy link

✅ Preview binaries are ready!

To test with modules: agentapi_version = "agentapi_172" or download from: https://github.com/coder/agentapi/releases/tag/agentapi_172

@johnstcn johnstcn marked this pull request as ready for review January 22, 2026 16:39
@mafredri mafredri changed the title chore(lib): extract Conversation interface refactor(lib): extract Conversation interface Jan 23, 2026
@mafredri
Copy link
Member

//cc @35C4n0r considering you're working on state serialization/restore.

Copy link
Member

@mafredri mafredri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid refactor! Added a few questions/suggestions inline.

@johnstcn johnstcn requested a review from 35C4n0r January 23, 2026 14:46
mu sync.RWMutex
logger *slog.Logger
conversation *st.Conversation
conversation *st.PTYConversation
Copy link
Collaborator

@35C4n0r 35C4n0r Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@johnstcn Shouldn't this be *st.Conversation ? (It's possible that I'm lacking the context/motive behind this refactor, If we have extracted an interface, shouldn't we be using it rather than coupling this to the concrete implementation ?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should, but there's some more coupling to be disentangled here before we can do that.

@35C4n0r
Copy link
Collaborator

35C4n0r commented Jan 27, 2026

//cc @35C4n0r considering you're working on state serialization/restore.

I'm building on top of this branch.

Copilot AI review requested due to automatic review settings February 3, 2026 16:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request refactors the screentracker package by extracting a Conversation interface and renaming the concrete implementation from Conversation to PTYConversation. The refactoring aims to provide better abstraction and support for potential alternative conversation implementations in the future.

Changes:

  • Extracted a Conversation interface with methods: Messages(), Send(), Start(), Status(), and Text()
  • Renamed screentracker.Conversation to screentracker.PTYConversation and ConversationConfig to PTYConversationConfig
  • Renamed methods for brevity: SendMessageSend, AddSnapshotSnapshot, StartSnapshotLoopStart, ScreenText
  • Moved and renamed FindNewMessage function to screenDiff in a new diff.go file with corresponding tests in diff_internal_test.go
  • Renamed error variables to follow Go conventions with Err prefix (e.g., MessageValidationErrorWhitespaceErrMessageValidationWhitespace)

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
lib/screentracker/conversation.go Defines the new Conversation interface and common types, removing the concrete implementation
lib/screentracker/pty_conversation.go Contains the renamed PTYConversation implementation with updated method names
lib/screentracker/diff.go New file containing the screenDiff function (formerly FindNewMessage)
lib/screentracker/diff_internal_test.go New test file for screenDiff function
lib/screentracker/pty_conversation_test.go Updated tests to use new type and method names, removed tests that were moved to diff_internal_test.go
lib/httpapi/server.go Updated to use new type name PTYConversation and renamed methods

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +32 to +38
for i, line := range newLines[dynamicHeaderEnd+1:] {
if !oldLinesMap[line] {
firstNonMatchingLine = i
break
}
}
newSectionLines := newLines[firstNonMatchingLine:]
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There appears to be a pre-existing bug in this logic that was moved from the original FindNewMessage function. When iterating over the sliced array newLines[dynamicHeaderEnd+1:], the index i is relative to the slice, not the full array. However, firstNonMatchingLine is then used to index into the full newLines array on line 38, which would give incorrect results.

For example, if dynamicHeaderEnd = 1 and the first non-matching line is at index 3 in the full array, the loop would set i = 1 (the index in the sliced array starting at position 2), but then newLines[1:] would start at the wrong position.

The fix should be: firstNonMatchingLine = i + dynamicHeaderEnd + 1 on line 34.

While this bug is pre-existing (moved from the original code), it could cause incorrect diff results when using the Opencode agent type with its dynamic header skipping logic.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants